#ifndef DATAPROC_H
#define DATAPROC_H


/* Determine the wordsize from the preprocessor defines.  */

#if defined __x86_64__ && !defined __ILP32__
# define __WORDSIZE	64
#else
# define __WORDSIZE	32
#endif

#ifdef __x86_64__
# define __WORDSIZE_TIME64_COMPAT32	1
/* Both x86-64 and x32 use the 64-bit system call interface.  */
# define __SYSCALL_WORDSIZE		64
#endif

/* There is some amount of overlap with <sys/types.h> as known by inet code */
#ifndef __int8_t_defined
# define __int8_t_defined
typedef signed char		int8_t;
typedef short int		int16_t;
typedef int			int32_t;
# if __WORDSIZE == 64
typedef long int		int64_t;
# else
__extension__
typedef long long int		int64_t;
# endif
#endif


#include <string>
#include <map>
#include <vector>
#include <stdlib.h>

#define START_10H 0x10    //固定长度报文启动字符
#define START_68H 0x68    //可变长度帧启动字符

#include "IEC103Type.h"

class DataProc
{
public:
    DataProc();
    bool ParseRecvData(const char* pData, int32_t dataLen);

protected:
    virtual bool ParseFixedData(const char* pData, int32_t dataLen);
    virtual bool ParseVariableData(const char* pData, int32_t dataLen);

protected:
    struct Point103
    {
        float       rate;
        std::string pubAddr;
    };

protected:
    /*
         * @Desc: 构造复位通信指令字符串
         * @Return: 复位通信指令字符串
         */
         std::vector<char> CmdResetCon();

        /*
         * @Desc: 构造复位帧计数位字符串
         * @Return: 复位通信指令字符串
         */
         std::vector<char> CmdResetNum();

        /*
         * @Desc: 指定控制域生成固定长度报文数据字符串
         * @Param: code
         * @Return: 固定长度报文数据字符串
         */
         std::vector<char> CmdFixedData(uint8_t code);


        /*
         * @Desc: 构造召唤一级数据指令字符串
         * @Return: 召唤一级数据指令字符串
         */
         std::vector<char> CmdGetDataLv1();

        /*
         * @Desc: 构造召唤二级数据指令字符串
         * @Return: 召唤二级数据指令字符串
         */
         std::vector<char> CmdGetDataLv2();

        /*
         * @Desc: 对时
         * @Return:
         */
         std::vector<char> CmdSetTimeStamp();


        /*
         * @Desc: 事件告警复归
         * @Return:
         */
         std::vector<char> CmdResetEventAlarm();

        /*
         * @Desc: 定值下传
         * @Return:
         */
         std::vector<char> CmdSettingDownload();

        /*
         * @Desc: 定值修改
         * @Return:
         */
         std::vector<char> CmdSettingModify();

        /*
         * @Desc: 构造总召唤指令字符串
         * @Return: 总召唤指令字符串
         */
         std::vector<char> CmdGetAll();

    //通用分类服务使用部分
        /*
         * @Desc: 构造通用分类读命令（读一个组所有条目的值）
         * @Param: groupNum要读的组号
         * @Return: 通用分类读命令字符串
         */
         std::vector<char> CmdGetGroupValue(uint8_t groupNo);

        /*
         * @Desc: 构造通用分类读命令（读一个组所有条目的值）
         * @Param: groupNum要读的组号
         * @Return: 通用分类读命令字符串
         */
         std::vector<char> CmdGetEntryValue(uint8_t groupNo, uint8_t entryNo);

        /*
         * @Desc: 生成较验码
         * @Param: packet 开始地址
         * @Param: length 开始地址
         * @Return: 较验码
         */
         uint8_t SumCheck( const char* packet, int32_t length );


         //遥测传输过程：主站以ASDU21发总召唤命令
         //           从站以ASDU10上送全遥测
         /*
          * @Desc: 解析通用分类数据响应（读目录，读一个组的描述，读一个组的值）
          * @Param: packet 开始地址
          * @Param: length 开始地址
          */
         virtual void ParseASDU10(const char* packet, int32_t length);
         //遥测传输过程：主站以ASDU21发总召唤命令
         //           从站以ASDU10上送全遥测
         /*
          * @Desc: 解析通用分类数据响应（读目录，读一个组的描述，读一个组的值）
          * @Param: packet 开始地址
          * @Param: length 开始地址
          */
         virtual void ParseASDU1(const char* packet, int32_t length);

private:
         virtual void ParseASDU10AllValue(const char* packet, int32_t length);
         std::string ToHexString(const char* data, int32_t dataLen);
         std::string GetGlobalAddrByPrivateAddr(std::string privateAddr);

private:
    IEC103CodeS2C m_iec103CodeS2C; //103控制域主到从
    CMD_SEND      m_nextCmd;       //下一条主站应该发送的指令

    uint8_t       m_clientAddr;  //从站地址
    static uint16_t      m_heartInterval; //秒

    std::map<std::string, Point103> m_pointAddrMap;  //<103点地址， 61850地址> 103地址和全局地址映射
    uint16_t      m_maxReSendTimes;       //重发次数
    uint16_t      m_sendInterval;         //重新发送间隔
    char          m_datapacket[MAX_SIZE]; //读到的数据

    bool          m_isResetConEnd;  //复位通信
    bool          m_isResetNumEnd;  //复位帧计数位
    bool          m_isGetAllEnd;    //总召唤

    uint8_t       m_ycGroupNum;
    uint8_t       m_yxGroupNum;

    uint8_t       m_GroupNo;
    uint8_t		  m_EntryNo;
    uint8_t       m_timeStampAddr;
};

#endif // DATAPROC_H
